package com.pan.crawler.auto2;

import com.pan.crawler.Directory;
import com.pan.crawler.auto2.action.NextPage;
import com.pan.crawler.auto2.action.RegexTool;
import com.pan.crawler.auto2.action.XPathFind;
import com.pan.crawler.factory.DriverFactory;
import com.pan.crawler.factory.EdgeDriverFactory;
import com.pan.entity.BookDirectory;
import com.pan.entity.Chapter;
import com.pan.download5.parse.entity.auto2.Auto2InfoDirectory;
import com.pan.download5.parse.entity.auto2.Auto2InfoValue;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;

import java.time.Duration;
import java.util.*;

public class Auto2CrawlerDirectory implements Directory {

    private Auto2InfoDirectory directoryInfo;

    public Auto2CrawlerDirectory(Auto2InfoDirectory directoryInfo) {
        this.directoryInfo = directoryInfo;
        //临时措施
        this.driverFactory = new EdgeDriverFactory();
    }
    private DriverFactory driverFactory;

    private XPathFind xPathFind;
    private RegexTool regexTool;

    {
        this.xPathFind = new XPathFind();
        this.regexTool = new RegexTool();
    }

    @Override
    public BookDirectory get(String url) {
        EdgeDriver edgeDriver = (EdgeDriver) driverFactory.getDriver();
//        EdgeOptions edgeOptions = new EdgeOptions();
//        edgeOptions.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

        edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        edgeDriver.navigate().to(url);

        BookDirectory bookDirectory = new BookDirectory();
        List<Chapter> chapterList = new LinkedList<>();
        bookDirectory.setChapterList(chapterList);

        Auto2InfoValue titleInfo = directoryInfo.getTitle();
        String titleXpath = titleInfo.getXpath();

        String title = xPathFind.find(edgeDriver, titleXpath);

        title = regexTool.handle(titleInfo.getRegex(), title);
        bookDirectory.setBookName(title);

        int id = 0;
        Auto2InfoValue chapName = directoryInfo.getChapName();
        String chapNameXpath = chapName.getXpath();
        String chapNameRegex = chapName.getRegex();
        Auto2InfoValue chapUrl = directoryInfo.getChapUrl();
        String chapUrlXpath = chapUrl.getXpath();
        String chapUrlRegex = chapUrl.getRegex();

        NextPage nextPage = new NextPage(directoryInfo.getNext());
        do {
            if (xPathFind.xpathElementEquals(chapUrlXpath, chapNameXpath)) {//如果是同一个元素就直接获取元素
                List<WebElement> elements = xPathFind.findElements(edgeDriver, chapNameXpath);
                String chapNameAttributeName = xPathFind.getAttributeName(chapNameXpath);
                String chapUrlAttributeName = xPathFind.getAttributeName(chapUrlXpath);
                for (WebElement e : elements) {
                    String cUrl = chapUrlAttributeName == null ? e.getText() : e.getAttribute(chapUrlAttributeName);
                    cUrl = regexTool.handle(chapUrlRegex, cUrl);
                    String cName = chapNameAttributeName == null ? e.getText() : e.getAttribute(chapNameAttributeName);
                    cName = regexTool.handle(chapNameRegex, cName);
                    Chapter chapter = new Chapter(id++, cName, cUrl);
                    chapterList.add(chapter);
                }
            } else {
                List<String> cns = xPathFind.finds(edgeDriver, chapNameXpath);
                List<String> cus = xPathFind.finds(edgeDriver, chapUrlXpath);
                if (cns.size() != cus.size()) {
                    throw new RuntimeException("ChapUrl or ChapName xpath ERROR: url xpath{" + chapUrlXpath + "}, name xpath{" + chapNameXpath + "}");
                }
                if (chapNameRegex.isEmpty() && chapUrlRegex.isEmpty()) {
                    for (int i = 0; i < cns.size(); i++) {
                        chapterList.add(new Chapter(id++, cns.get(i), cus.get(i)));
                    }
                } else if (chapNameRegex.isEmpty()) {
                    for (int i = 0; i < cns.size(); i++) {
                        chapterList.add(new Chapter(id++,
                                cns.get(i),
                                regexTool.handle(chapUrlRegex, cus.get(i))
                        ));
                    }
                } else if (chapUrlRegex.isEmpty()) {
                    for (int i = 0; i < cns.size(); i++) {
                        chapterList.add(new Chapter(id++,
                                regexTool.handle(chapNameRegex, cns.get(i)),
                                cus.get(i)
                        ));
                    }
                } else {
                    for (int i = 0; i < cns.size(); i++) {
                        chapterList.add(new Chapter(id++,
                                regexTool.handle(chapNameRegex, cns.get(i)),
                                regexTool.handle(chapUrlRegex, cus.get(i))));
                    }
                }

            }
        } while (nextPage.next(edgeDriver));
        if (bookDirectory.getChapterList().size() == 0) {
            throw new RuntimeException("未获得章节列表： chapUrl xpath=" + chapUrlXpath + ", chapName xpath=" + chapNameXpath);
        }
        edgeDriver.quit();

        //章节去重
        bookDirectory.setChapterList(deduplication(bookDirectory.getChapterList()));
        return bookDirectory;
    }

    public List<Chapter> deduplication(List<Chapter> chapterList) {
        HashMap<String, Chapter> urlChapMap = new HashMap<>();
        Set<Integer> repeatedIndexSet = new HashSet<>();
        for (Chapter c : chapterList) {
            String url = c.getUrl();
            if (urlChapMap.containsKey(url)){
                Chapter repeatedChapter = urlChapMap.get(url);
                int repeatedId = repeatedChapter.getId();
                repeatedIndexSet.add(repeatedId);
            }
            urlChapMap.put(url, c);
        }
        int resultSize = urlChapMap.size();
        List<Chapter> resultList = new ArrayList<>(resultSize);
        for (int i = 0,index = 0; i < chapterList.size(); i++) {
            if (!repeatedIndexSet.contains(i)){
                Chapter chapter = chapterList.get(i);
                chapter.setId(index++);
                resultList.add(chapter);
            }
        }
        return resultList;
    }




}
/**
 * JavascriptExecutor jsExecutor = (JavascriptExecutor) edgeDriver;
 * l1: for(int j= 0;;j++) {
 * l0:for (int i = 0; i < 10; i++) {
 * //1.loading（正在加载）、
 * //2.interactive（文档已被解析，
 * //3.DOM 树构建完成，但是诸如图片、样式表和框架之类的外部资源可能尚未完全加载）
 * //4.complete（页面以及所有子资源已完成加载）。
 * String readyState = (String) jsExecutor.executeScript("return document.readyState");
 * if (readyState.equals("complete")) {
 * break l1;
 * }
 * try {
 * Thread.sleep(1000);
 * } catch (InterruptedException e) {
 * throw new RuntimeException(e);
 * }
 * }
 * if (j >= 2) {
 * throw new TimeoutException("加载页面失败： "+url);
 * }else {
 * edgeDriver.navigate().refresh();
 * }
 * }
 */